_require       "./Bool.smi"
_require       "./Char.smi"
_require       "./General.smi"
_require       "./IntInf.smi"
_require       "./List.smi"
_require       "./Option.smi"
_require       "./Real64.smi"
_require       "./String.smi"
_require       "./Substring.smi"
_require       "./Vector.smi"
_require       "../../smlnj/Basis/IO/text-io.smi"

infix 7 * / div mod
infix 6 + - ^
infixr 5 :: @
infix 4 = <> > >= < <=
infix 3 := o
infix 0 before

type substring = Substring.substring
datatype order = datatype General.order

exception Empty = List.Empty
exception Option = Option.Option
exception Span = General.Span

val ! = General.!
val @ = List.@
val := = General.:=
val ^ = String.^
val app = List.app
val before = General.before
val ceil = Real64.ceil
val chr = Char.chr
val concat = String.concat
val exnMessage = General.exnMessage
val exnName = General.exnName
val explode = String.explode
val floor = Real64.floor
val foldl = List.foldl
val foldr = List.foldr
val getOpt = Option.getOpt
val hd = List.hd
val ignore = General.ignore
val implode = String.implode
val isSome = Option.isSome
val length = List.length
val map = List.map
val not = Bool.not
val null = List.null
val o = General.o
val ord = Char.ord
val print = TextIO.print
val real = Real64.fromInt
val rev = List.rev
val round = Real64.round
val size = String.size
val str = String.str
val substring = String.substring
val tl = List.tl
val trunc = Real64.trunc
val valOf = Option.valOf
val vector = Vector.fromList

(* 2016-07-10: ohori
   I have replaced "SMLSharp_Builtin.Int32.int" etc with int etc;
   they are primitive types so we should use the primitive name.
val + =
    case 'a in 'a * 'a -> 'a of
      SMLSharp_Builtin.Int32.int => SMLSharp_Builtin.Int32.add_unsafe  (*FIXME*)
    | SMLSharp_Builtin.Word32.word => SMLSharp_Builtin.Word32.add
    | SMLSharp_Builtin.Int64.int => SMLSharp_Builtin.Int64.add_unsafe  (*FIXME*)
    | SMLSharp_Builtin.Word64.word => SMLSharp_Builtin.Word64.add
    | SMLSharp_Builtin.Word8.word => SMLSharp_Builtin.Word8.add
    | IntInf.int => IntInf.+
    | SMLSharp_Builtin.Real64.real => SMLSharp_Builtin.Real64.add
    | SMLSharp_Builtin.Real32.real => SMLSharp_Builtin.Real32.add
*)


val + =
    case 'a in 'a * 'a -> 'a of
      int => SMLSharp_Builtin.Int32.add_unsafe  (*FIXME*)
    | word => SMLSharp_Builtin.Word32.add
    | int8 => SMLSharp_Builtin.Int8.add_unsafe  (*FIXME*)
    | word8 => SMLSharp_Builtin.Word8.add
    | int16 => SMLSharp_Builtin.Int16.add_unsafe  (*FIXME*)
    | word16 => SMLSharp_Builtin.Word16.add
    | int64 => SMLSharp_Builtin.Int64.add_unsafe  (*FIXME*)
    | word64 => SMLSharp_Builtin.Word64.add
    | intInf => IntInf.+
    | real => SMLSharp_Builtin.Real64.add
    | real32 => SMLSharp_Builtin.Real32.add

val - =
    case 'a in 'a * 'a -> 'a of
      int => SMLSharp_Builtin.Int32.sub_unsafe  (*FIXME*)
    | word => SMLSharp_Builtin.Word32.sub
    | int8 => SMLSharp_Builtin.Int8.sub_unsafe  (*FIXME*)
    | word8 => SMLSharp_Builtin.Word8.sub
    | int16 => SMLSharp_Builtin.Int16.sub_unsafe  (*FIXME*)
    | word16 => SMLSharp_Builtin.Word16.sub
    | int64 => SMLSharp_Builtin.Int64.sub_unsafe  (*FIXME*)
    | word64 => SMLSharp_Builtin.Word64.sub
    | intInf => IntInf.-
    | real => SMLSharp_Builtin.Real64.sub
    | real32 => SMLSharp_Builtin.Real32.sub

val * =
    case 'a in 'a * 'a -> 'a of
      int => SMLSharp_Builtin.Int32.mul_unsafe  (*FIXME*)
    | word => SMLSharp_Builtin.Word32.mul
    | int8 => SMLSharp_Builtin.Int8.mul_unsafe  (*FIXME*)
    | word8 => SMLSharp_Builtin.Word8.mul
    | int16 => SMLSharp_Builtin.Int16.mul_unsafe  (*FIXME*)
    | word16 => SMLSharp_Builtin.Word16.mul
    | int64 => SMLSharp_Builtin.Int64.mul_unsafe  (*FIXME*)
    | word64 => SMLSharp_Builtin.Word64.mul
    | intInf => IntInf.*
    | real => SMLSharp_Builtin.Real64.mul
    | real32 => SMLSharp_Builtin.Real32.mul

val div =
    case 'a in 'a * 'a -> 'a of
      int => SMLSharp_Builtin.Int32.div
    | word => SMLSharp_Builtin.Word32.div
    | int8 => SMLSharp_Builtin.Int8.div
    | word8 => SMLSharp_Builtin.Word8.div
    | int16 => SMLSharp_Builtin.Int16.div
    | word16 => SMLSharp_Builtin.Word16.div
    | int64 => SMLSharp_Builtin.Int64.div
    | word64 => SMLSharp_Builtin.Word64.div
    | intInf => IntInf.div

val mod =
    case 'a in 'a * 'a -> 'a of
      int => SMLSharp_Builtin.Int32.mod
    | word => SMLSharp_Builtin.Word32.mod
    | int8 => SMLSharp_Builtin.Int8.mod
    | word8 => SMLSharp_Builtin.Word8.mod
    | int16 => SMLSharp_Builtin.Int16.mod
    | word16 => SMLSharp_Builtin.Word16.mod
    | int64 => SMLSharp_Builtin.Int64.mod
    | word64 => SMLSharp_Builtin.Word64.mod
    | intInf => IntInf.mod

val / =
    case 'a in 'a * 'a -> 'a of
      real => SMLSharp_Builtin.Real64.div
    | real32 => SMLSharp_Builtin.Real32.div

val ~ =
    case 'a in 'a -> 'a of
      int => SMLSharp_Builtin.Int32.neg
    | word => SMLSharp_Builtin.Word32.neg
    | int8 => SMLSharp_Builtin.Int8.neg
    | word8 => SMLSharp_Builtin.Word8.neg
    | int16 => SMLSharp_Builtin.Int16.neg
    | word16 => SMLSharp_Builtin.Word16.neg
    | int64 => SMLSharp_Builtin.Int64.neg
    | word64 => SMLSharp_Builtin.Word64.neg
    | intInf => IntInf.~
    | real => SMLSharp_Builtin.Real64.neg
    | real32 => SMLSharp_Builtin.Real32.neg

val abs =
    case 'a in 'a -> 'a of
      int => SMLSharp_Builtin.Int32.abs
    | int8 => SMLSharp_Builtin.Int8.abs
    | int16 => SMLSharp_Builtin.Int16.abs
    | int64 => SMLSharp_Builtin.Int64.abs
    | real => SMLSharp_Builtin.Real64.abs
    | real32 => SMLSharp_Builtin.Real32.abs
    | intInf => IntInf.abs

val < =
    case 'a in 'a * 'a -> bool of
      int => SMLSharp_Builtin.Int32.lt
    | word => SMLSharp_Builtin.Word32.lt
    | int8 => SMLSharp_Builtin.Int8.lt
    | word8 => SMLSharp_Builtin.Word8.lt
    | int16 => SMLSharp_Builtin.Int16.lt
    | word16 => SMLSharp_Builtin.Word16.lt
    | int64 => SMLSharp_Builtin.Int64.lt
    | word64 => SMLSharp_Builtin.Word64.lt
    | intInf => IntInf.<
    | real => SMLSharp_Builtin.Real64.lt
    | real32 => SMLSharp_Builtin.Real32.lt
    | string => String.<
    | char => SMLSharp_Builtin.Char.lt

val > =
    case 'a in 'a * 'a -> bool of
      int => SMLSharp_Builtin.Int32.gt
    | word => SMLSharp_Builtin.Word32.gt
    | int8 => SMLSharp_Builtin.Int8.gt
    | word8 => SMLSharp_Builtin.Word8.gt
    | int16 => SMLSharp_Builtin.Int16.gt
    | word16 => SMLSharp_Builtin.Word16.gt
    | int64 => SMLSharp_Builtin.Int64.gt
    | word64 => SMLSharp_Builtin.Word64.gt
    | intInf => IntInf.>
    | real => SMLSharp_Builtin.Real64.gt
    | real32 => SMLSharp_Builtin.Real32.gt
    | string => String.>
    | char => SMLSharp_Builtin.Char.gt

val <= =
    case 'a in 'a * 'a -> bool of
      int => SMLSharp_Builtin.Int32.lteq
    | word => SMLSharp_Builtin.Word32.lteq
    | int8 => SMLSharp_Builtin.Int8.lteq
    | word8 => SMLSharp_Builtin.Word8.lteq
    | int16 => SMLSharp_Builtin.Int16.lteq
    | word16 => SMLSharp_Builtin.Word16.lteq
    | int64 => SMLSharp_Builtin.Int64.lteq
    | word64 => SMLSharp_Builtin.Word64.lteq
    | intInf => IntInf.<=
    | real => SMLSharp_Builtin.Real64.lteq
    | real32 => SMLSharp_Builtin.Real32.lteq
    | string => String.<=
    | char => SMLSharp_Builtin.Char.lteq

val >= =
    case 'a in 'a * 'a -> bool of
      int => SMLSharp_Builtin.Int32.gteq
    | word => SMLSharp_Builtin.Word32.gteq
    | int8 => SMLSharp_Builtin.Int8.gteq
    | word8 => SMLSharp_Builtin.Word8.gteq
    | int16 => SMLSharp_Builtin.Int16.gteq
    | word16 => SMLSharp_Builtin.Word16.gteq
    | int64 => SMLSharp_Builtin.Int64.gteq
    | word64 => SMLSharp_Builtin.Word64.gteq
    | intInf => IntInf.>=
    | real => SMLSharp_Builtin.Real64.gteq
    | real32 => SMLSharp_Builtin.Real32.gteq
    | string => String.>=
    | char => SMLSharp_Builtin.Char.gteq
